---
id: dbcontext-multi-database
title: 9.18 多数据库操作
sidebar_label: 9.18 多数据库操作
---

import useBaseUrl from "@docusaurus/useBaseUrl";
import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";

:::warning 连接字符串配置注意事项

如果连接字符串是配置在自定义的 `.json` 文件中，那么必须在 `Visual Studio` 中配置 `.json` 右键属性，设置 `复制` 输出目录为 `如果较新则复制`，生成操作为 `内容`。

否则就会提示找不到配置或连接字符串的错误。

:::

## 9.18.1 `Furion` 支持数据库提供器

| SqlServer | Sqlite | Cosmos | InMemoryDatabase | MySql | PostgreSQL | Oracle | Firebird | Dm  |
| --------- | ------ | ------ | ---------------- | ----- | ---------- | ------ | -------- | --- |
| ✔         | ✔      | ✔      | ✔                | ✔     | ✔          | ✔      | ✔        | ✔   |

### 9.18.1.1 数据库提供器对应包

- `SqlServer`：`Microsoft.EntityFrameworkCore.SqlServer` (支持 SqlServer 2005 +)
- `Sqlite`：`Microsoft.EntityFrameworkCore.Sqlite`
- `Cosmos`：`Microsoft.EntityFrameworkCore.Cosmos`
- `InMemoryDatabase`：`Microsoft.EntityFrameworkCore.InMemory`
- `MySql`
  - `Pomelo.EntityFrameworkCore.MySql`，**Nuget 需勾选预览版且安装 .Alpha.2 版本** (支持 MySql 5.x +)
  - `MySql.EntityFrameworkCore`：支持 (MySql 8.x +)
- `PostgreSQL`：`Npgsql.EntityFrameworkCore.PostgreSQL`
- `Oracle`：`Oracle.EntityFrameworkCore` （支持 Oracle 10 +）
- `Firebird`：`FirebirdSql.EntityFrameworkCore.Firebird`
- `Dm`：`Microsoft.EntityFrameworkCore.Dm`

:::tip 小知识

这些数据库包应该安装在 `Furion.EntityFramework.Core` 层。特殊情况需安装在 `Furion.Core` 层中，如 `Mysql` `HasCharset()` 配置。

:::

## 9.18.2 多数据库服务注册

```cs
// 注册 SqlServer
options.AddDbPool<FurionDbContext>(DbProvider.SqlServer);
options.AddDbPool<FurionDbContext>($"{DbProvider.SqlServer}@2005"); // 支持 2005 数据库
options.AddDbPool<FurionDbContext>($"{DbProvider.SqlServer}@2008"); // 支持 2008 数据库

// 注册 Sqlite
options.AddDbPool<FurionDbContext>(DbProvider.Sqlite);

// 注册 Cosmos
options.AddDbPool<FurionDbContext>(DbProvider.Cosmos);

// 注册 InMemoryDatabase
options.AddDbPool<FurionDbContext>(DbProvider.InMemoryDatabase);

// 注册 MySql
options.AddDbPool<FurionDbContext>(DbProvider.MySql);
options.AddDbPool<FurionDbContext>($"{DbProvider.MySql}@8.0.22");  // 可以指定版本号
options.AddDbPool<FurionDbContext>(DbProvider.MySqlOfficial);   // 使用 MySql 官方包（MySql.EntityFrameworkCore）

// 注册 PostgreSQL
options.AddDbPool<FurionDbContext>(DbProvider.Npgsql);

// 注册 Oracle
options.AddDbPool<FurionDbContext>(DbProvider.Oracle);
options.AddDbPool<FurionDbContext>($"{DbProvider.Oracle}@11");  // 支持 Oracle 11 版本

// 注册 Firebird
options.AddDbPool<FurionDbContext>(DbProvider.Firebird);

// 注册 Dm
options.AddDbPool<FurionDbContext>(DbProvider.Dm);
```

:::caution 新版 SqlServer/MySQL/Oracle 注意

`SqlServer` 兼容 `2005-2008` 写法：

```cs
services.AddDatabaseAccessor(options =>
{
    options.AddDbPool<FurionDbContext>($"{DbProvider.SqlServer}@2005"); // 支持 2005 数据库
    options.AddDbPool<FurionDbContext>($"{DbProvider.SqlServer}@2008"); // 支持 2008 数据库
});
```

`MySQL` 兼容旧版本（带版本号）写法：

```cs
services.AddDatabaseAccessor(options =>
{
    options.AddDbPool<FurionDbContext>($"{DbProvider.MySql}@8.0.22");
});
```

如果使用了 `MySql.EntityFrameworkCore` 包，则需改为以下注册：

```cs
services.AddDatabaseAccessor(options =>
{
    options.AddDbPool<FurionDbContext>(DbProvider.MySqlOfficial);
});
```

`Oracle` 兼容 `11` 版本

```cs
services.AddDatabaseAccessor(options =>
{
    options.AddDbPool<FurionDbContext>($"{DbProvider.Oracle}@11");
});
```

:::

## 9.18.3 多数据库使用方式

`Furion` 通过独创的 `数据库上下文定位器` 实现多数据库灵活操作切换。只需要为每一种数据库绑定唯一的数据库上下文定位器即可。

以下是 `Furion` 支持多数据库操作的实例：

### 9.18.3.1 实体仓储方式

```cs
// 切换到 MSSQL 操作 Person表
var mssqlRepository = personRepository.Change<Person, MsSqlDbContextLocator>();

// 切换到 MySql 操作 Person表
var mysqlRepository = personRepository.Change<Person, MySqlDbContextLocator>();

// 切换到 Sqlite 操作 Person表
var sqliteRepository = personRepository.Change<Person, SqliteDbContextLocator>();

```

### 9.18.3.2 非泛型仓储方式

```cs
// 切换到 MSSQL 操作 Person表
var mssqlRepository = repository.Change<Person, MsSqlDbContextLocator>();

// 切换到 MySql 操作 Person表
var mysqlRepository = repository.Change<Person, MySqlDbContextLocator>();

// 切换到 Sqlite 操作 Person表
var sqliteRepository = repository.Change<Person, SqliteDbContextLocator>();
```

### 9.18.3.3 `Sql` 仓储方式

```cs
// 切换到 MSSQL 操作 Person表
var mssqlRepository = sqlRepository.Change<MsSqlDbContextLocator>();

// 切换到 MySql 操作 Person表
var mysqlRepository = sqlRepository.Change<MySqlDbContextLocator>();

// 切换到 Sqlite 操作 Person表
var sqliteRepository = sqlRepository.Change<SqliteDbContextLocator>();
```

### 9.18.3.4 实体定义方式

```cs

// 支持一个数据库
public class Person: IEntity<MySqlDbContextLocator>
{
    // ....
}

// 支持多个数据库
public class Person: IEntity<MySqlDbContextLocator, SqliteDbContextLocator>
{
    // ....
}
```

:::tip 小知识

所有的 `实体依赖接口或抽象类` 都支持泛型方式 指定 数据库上下文定位器，最多支持 `8` 个。

:::

### 9.18.3.5 Linq 函数方式

```cs
public static class QueryFunctions
{
    [QueryableFunction("FN_GetId", "dbo", typeof(MySqlDbContextLocator), typeof(SqliteDbContextLocator))]
    public static int GetId(int id) => throw new NotSupportedException();
}
```

## 9.18.4 反馈与建议

:::note 与我们交流

给 Furion 提 [Issue](https://gitee.com/dotnetchina/Furion/issues/new?issue)。

:::
